package freespiritsocial.io.user.ui.fragment.home

import android.os.Bundle
import android.view.View
import android.widget.FrameLayout
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.os.bundleOf
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.recyclerview.widget.GridLayoutManager
import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.SupportMapFragment
import com.google.android.gms.maps.model.MapStyleOptions
import com.google.android.gms.maps.model.Marker
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.scwang.smart.refresh.layout.util.SmartUtil.dp2px
import freespiritsocial.io.user.R
import freespiritsocial.io.user.base.BaseFragment
import freespiritsocial.io.user.databinding.FrgMapBinding
import freespiritsocial.io.user.ext.init
import freespiritsocial.io.user.handle.BackHandle
import freespiritsocial.io.user.ui.adapter.PostAdapter
import freespiritsocial.io.user.ui.fragment.home.ExploreFrg.Companion.defLatLng
import freespiritsocial.io.user.ui.fragment.post.PostDetailFrg
import freespiritsocial.io.user.ui.helper.MarkerHelper
import freespiritsocial.io.user.ui.helper.MarkerHelper.changeZoom
import freespiritsocial.io.user.viewmodel.MapViewModel
import me.hgj.jetpackmvvm.ext.nav
import me.hgj.jetpackmvvm.ext.navigateAction
import me.hgj.jetpackmvvm.ext.util.loge
import me.hgj.jetpackmvvm.ext.util.screenHeight

/**
 * @description 地圖頁
 */
class MapFrg: BaseFragment<MapViewModel,FrgMapBinding>(),OnMapReadyCallback {
    var map: GoogleMap? = null
    var curMarker: Marker? = null
    private val postAdapter by lazy(LazyThreadSafetyMode.NONE) {
        PostAdapter().apply {
            setOnItemClickListener { _,_,position ->
                mViewModel.getPost(data[position].invitationId)
            }
        }
    }
    val fragmentView: View? by lazy(LazyThreadSafetyMode.NONE) {
        (childFragmentManager.findFragmentById(R.id.map) as? SupportMapFragment)?.view
    }
    val fragmentHeight: Int by lazy(LazyThreadSafetyMode.NONE) {
        fragmentView?.height ?: 0
    }
    private val behavior: BottomSheetBehavior<FrameLayout> by lazy {
        val layoutParams = mDatabind.bottomSheet.layoutParams as CoordinatorLayout.LayoutParams
        layoutParams.height = requireContext().screenHeight - dp2px(200f)
        BottomSheetBehavior.from<FrameLayout>(mDatabind.bottomSheet)
    }

    override fun layoutId(): Int = R.layout.frg_map

    override fun initView(savedInstanceState: Bundle?) = with(mDatabind) {
        click = Click()
        recyclerView.init(
            postAdapter,
            GridLayoutManager(requireContext(),2),
            emptyText = "No one has posted any posts yet.",
            emptyImage = R.mipmap.empty_home
        )
        behavior.addBottomSheetCallback(object: BottomSheetBehavior.BottomSheetCallback() {
            override fun onStateChanged(bottomSheet: View,newState: Int) {

            }

            override fun onSlide(bottomSheet: View,slideOffset: Float) {
                fragmentView?.updateLayoutParams {
                    height = (fragmentHeight - (mDatabind.bottomSheet.height * slideOffset)).toInt() + behavior.peekHeight
                    height.toString().loge("Csw")
                }
            }

        })
    }

    override fun createObserver() {
        super.createObserver()
        mViewModel.postItemResult.observe(this) {
            nav().navigateAction(
                R.id.postDetailFrg,
                bundle = bundleOf(PostDetailFrg.KEY_DATA to it)
            )
        }

        eventViewModel.savePostEvent.observe(this) {
            val postPojo = postAdapter.data.find { data -> data.invitationId == it } ?: return@observe
            postPojo.isSave = postPojo.isSave?.not()
            postAdapter.notifyItemChanged(postAdapter.data.indexOf(postPojo))
        }
        eventViewModel.hidePostEvent.observe(this) {
            val postPojo = postAdapter.data.find { data -> data.invitationId == it } ?: return@observe
            postAdapter.remove(postPojo)
        }
        eventViewModel.delPostEvent.observe(this) {
            val postPojo = postAdapter.data.find { data -> data.invitationId == it } ?: return@observe
            postAdapter.remove(postPojo)
        }
        eventViewModel.likePostEvent.observe(this) {
            val postPojo = postAdapter.data.find { data -> data.invitationId == it } ?: return@observe
            postPojo.isLike = postPojo.isLike?.not()
            postPojo.likeCount += if (postPojo.isLike == true) 1 else -1
            postAdapter.notifyItemChanged(postAdapter.data.indexOf(postPojo))
        }
    }

    override fun lazyLoadData() {
        loadMap()
    }

    private fun loadMap() {
        (childFragmentManager.findFragmentById(R.id.map) as SupportMapFragment).getMapAsync(this)
    }

    inner class Click: BackHandle {
        fun location() {
            map?.animateCamera(CameraUpdateFactory.newLatLngZoom(defLatLng,MarkerHelper.curZoom));//DEFAULT_ZOOM
        }

        override fun goBack() {
            nav().navigateUp()
        }

    }

    override fun onMapReady(p0: GoogleMap) {
        map = p0
        p0.setMapStyle(MapStyleOptions.loadRawResourceStyle(requireContext(),R.raw.style_json))
        p0.moveCamera(CameraUpdateFactory.newLatLngZoom(appViewModel.curLatLng.value ?: defLatLng,MarkerHelper.curZoom))
        MarkerHelper.parseMarker(p0)
        p0.setOnCameraMoveListener {
            changeZoom(p0.cameraPosition.zoom)
            appViewModel.curLatLng.postValue(map?.cameraPosition?.target)
        }
        p0.setOnMarkerClickListener { marker ->
            if (curMarker == marker) return@setOnMarkerClickListener true
            MarkerHelper.changeMarkerIcon(false,curMarker)
            MarkerHelper.changeMarkerIcon(true,marker)
            curMarker = marker
            val name = marker.tag as String
            mDatabind.tvAddress.text = name
            mDatabind.bottomSheet.isVisible = true
            mViewModel.getAreaPostList0(name) {
                postAdapter.setList(it)
            }
            behavior.state = BottomSheetBehavior.STATE_EXPANDED
            p0.moveCamera(CameraUpdateFactory.newLatLngZoom(marker.position,MarkerHelper.curZoom))
            appViewModel.curLatLng.postValue(marker.position)
            return@setOnMarkerClickListener true
        }
    }
}